package zpp_nape.dynamics;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class ZPP_SpaceArbiterList extends ArbiterList{
    public var space:ZPP_Space;
    public var _length:Int;
    public var zip_length:Bool;
    public function new(){
        super();
        at_index_0=0;
        at_index_1=0;
        at_index_2=0;
        at_index_3=0;
        zip_length=true;
        _length=0;
        lengths=new Array<Int>();
        for(i in 0...4)lengths.push(0);
    }
    public inline override function zpp_gl(){
        zpp_vm();
        if(zip_length){
            _length=0;
            var ind=0;
            {
                {
                    var len=0;
                    {
                        var cx_ite=space.c_arbiters_true.begin();
                        while(cx_ite!=null){
                            var i=cx_ite.elem();
                            if(i.active)len++;
                            cx_ite=cx_ite.next;
                        }
                    };
                    lengths[ind++]=len;
                    _length+=len;
                };
                {
                    var len=0;
                    {
                        var cx_ite=space.c_arbiters_false.begin();
                        while(cx_ite!=null){
                            var i=cx_ite.elem();
                            if(i.active)len++;
                            cx_ite=cx_ite.next;
                        }
                    };
                    lengths[ind++]=len;
                    _length+=len;
                };
                {
                    var len=0;
                    {
                        var cx_ite=space.f_arbiters.begin();
                        while(cx_ite!=null){
                            var i=cx_ite.elem();
                            if(i.active)len++;
                            cx_ite=cx_ite.next;
                        }
                    };
                    lengths[ind++]=len;
                    _length+=len;
                };
                {
                    var len=0;
                    {
                        var cx_ite=space.s_arbiters.begin();
                        while(cx_ite!=null){
                            var i=cx_ite.elem();
                            if(i.active)len++;
                            cx_ite=cx_ite.next;
                        }
                    };
                    lengths[ind++]=len;
                    _length+=len;
                };
            };
            zip_length=false;
        }
        return _length;
    }
    public var lengths:Array<Int>;
    public var ite_0:ZNPNode_ZSD;
    public var ite_1:ZNPNode_ZDD;
    public var ite_2:ZNPNode_ZPP_FluidArbiter;
    public var ite_3:ZNPNode_ZPP_SensorArbiter;
    public var at_index_0:Int;
    public var at_index_1:Int;
    public var at_index_2:Int;
    public var at_index_3:Int;
    public inline override function zpp_vm(){
        var modified=false;
        {
            if(space.c_arbiters_true.modified){
                modified=true;
                space.c_arbiters_true.modified=false;
            };
            if(space.c_arbiters_false.modified){
                modified=true;
                space.c_arbiters_false.modified=false;
            };
            if(space.f_arbiters.modified){
                modified=true;
                space.f_arbiters.modified=false;
            };
            if(space.s_arbiters.modified){
                modified=true;
                space.s_arbiters.modified=false;
            };
        };
        if(modified){
            if(zpp_inner.iterators!=null){
                {
                    var cx_ite=zpp_inner.iterators.begin();
                    while(cx_ite!=null){
                        var i=cx_ite.elem();
                        {
                            if(i.zpp_critical)throw "Error: Lists should never be modified once hasNext() has been called, and before next() has been called on iterators to the list as it is not defined behaviour. In this case it appears that you are using api functions that modify this list between hasNext() and next() calls which bypass the usual checks.";
                        };
                        cx_ite=cx_ite.next;
                    }
                };
            }
            zip_length=true;
            _length=0;
            ite_0=null;
            ite_1=null;
            ite_2=null;
            ite_3=null;
        }
    }
    public inline override function push(obj:Arbiter):Bool{
        throw "Error: ArbiterList is immutable";
        return false;
    }
    public inline override function pop():Arbiter{
        throw "Error: ArbiterList is immutable";
        return null;
    }
    public inline override function unshift(obj:Arbiter):Bool{
        throw "Error: ArbiterList is immutable";
        return false;
    }
    public inline override function shift():Arbiter{
        throw "Error: ArbiterList is immutable";
        return null;
    }
    public inline override function remove(obj:Arbiter):Bool{
        throw "Error: ArbiterList is immutable";
        return false;
    }
    public inline override function at(index:Int):Arbiter{
        zpp_vm();
        if(index<0||index>=length)throw "Error: Index out of bounds";
        var ret:Arbiter=null;
        var accum_length=0;
        
        if(ret==null){
            if(index<accum_length+lengths[0]){
                var offset=index-accum_length;
                if(offset<at_index_0||ite_0==null){
                    at_index_0=0;
                    ite_0=space.c_arbiters_true.begin();
                    while(true){
                        var x=ite_0.elem();
                        if(x.active)break;
                        ite_0=ite_0.next;
                    }
                }
                while(at_index_0!=offset){
                    at_index_0++;
                    ite_0=ite_0.next;
                    while(true){
                        var x=ite_0.elem();
                        if(x.active)break;
                        ite_0=ite_0.next;
                    }
                }
                ret=ite_0.elem().wrapper();
            }
            else accum_length+=lengths[0];
        }
        if(ret==null){
            if(index<accum_length+lengths[1]){
                var offset=index-accum_length;
                if(offset<at_index_1||ite_1==null){
                    at_index_1=0;
                    ite_1=space.c_arbiters_false.begin();
                    while(true){
                        var x=ite_1.elem();
                        if(x.active)break;
                        ite_1=ite_1.next;
                    }
                }
                while(at_index_1!=offset){
                    at_index_1++;
                    ite_1=ite_1.next;
                    while(true){
                        var x=ite_1.elem();
                        if(x.active)break;
                        ite_1=ite_1.next;
                    }
                }
                ret=ite_1.elem().wrapper();
            }
            else accum_length+=lengths[1];
        }
        if(ret==null){
            if(index<accum_length+lengths[2]){
                var offset=index-accum_length;
                if(offset<at_index_2||ite_2==null){
                    at_index_2=0;
                    ite_2=space.f_arbiters.begin();
                    while(true){
                        var x=ite_2.elem();
                        if(x.active)break;
                        ite_2=ite_2.next;
                    }
                }
                while(at_index_2!=offset){
                    at_index_2++;
                    ite_2=ite_2.next;
                    while(true){
                        var x=ite_2.elem();
                        if(x.active)break;
                        ite_2=ite_2.next;
                    }
                }
                ret=ite_2.elem().wrapper();
            }
            else accum_length+=lengths[2];
        }
        if(ret==null){
            if(index<accum_length+lengths[3]){
                var offset=index-accum_length;
                if(offset<at_index_3||ite_3==null){
                    at_index_3=0;
                    ite_3=space.s_arbiters.begin();
                    while(true){
                        var x=ite_3.elem();
                        if(x.active)break;
                        ite_3=ite_3.next;
                    }
                }
                while(at_index_3!=offset){
                    at_index_3++;
                    ite_3=ite_3.next;
                    while(true){
                        var x=ite_3.elem();
                        if(x.active)break;
                        ite_3=ite_3.next;
                    }
                }
                ret=ite_3.elem().wrapper();
            }
            else accum_length+=lengths[3];
        }
        return ret;
    }
}
